Información general
Descripción
Las pruebas de mutación están diseñadas para comprobar la calidad del código y las pruebas unitarias desarrolladas. Para esas pruebas unitarias, en lugar de verificar si el código se comporta correctamente en función de entradas conocidas, las pruebas de mutación modifican deliberadamente partes del código fuente, generando versiones alternativas (llamadas mutantes) para ver si las pruebas unitarias existentes detectan estos cambios durante su ejecución. Es decir, miden la calidad de las pruebas unitarias desarrolla-das.
Si una prueba unitaria no detecta el error introducido por la herramienta de mutación (es decir, no falla cuando debería), significa que esa prueba es débil o insuficiente. Se podría pulir el código fuente sobre el que se hacen las pruebas ya sea a nivel matemático, lógico o revisando los retornos de resultados entre otros aspectos que se comprueban con las pruebas de mutación.
Estas herramientas de mutación están integradas en el pipeline de integración continua utilizado por la Plataforma de CI/CD Corporativa, de forma que cuando se realice el proceso de CI de un componente en dicha plataforma se ejecutarán las pruebas de mutación generando un informe con el resultado de las mismas.
Funcionamiento de las pruebas de mutación
La ejecución de las pruebas de mutación consta de varios pasos:
1. Generación de mutantes
Se generan N mutantes. Cada mutante tiene UN único cambio, que altera un operador o condición (cambiar un + por -, quitar un if, cambiar > por >=).
Cualquier parte del código cuya lógica pueda ser alterada por la herramienta de mutación para generar código artificial erróneo se considera un “punto de mutación”. De dicho punto de mutación salen tantos mutantes como mutaciones posibles tenga ese punto. Por ejemplo, para un punto de mutación de tipo aritmético, salen tres mutantes, ya que existen cuatro operaciones aritméticas (+, -, /, *).
El número de mutantes es la suma de posibilidades de todos los puntos de mutación. Nótese que el número de mutantes generados es completamente independiente de la cantidad de pruebas unitarias existentes. Por lo general, el número de mutantes generados escala de manera lineal con el tamaño del código fuente (excluyendo las pruebas unitarias)
2. Ejecución de pruebas unitarias para cada mutante
Para cada mutante, la herramienta lanza las pruebas unitarias, parando únicamente cuando el mutante muere (o sobrevive a todas las pruebas unitarias)
Las herramientas de mutación optimizan la ejecución de las pruebas. Por lo general, no lanzan pruebas unitarias para un mutante si detectan que dicho mutante no afecta a la ejecución de dicha prueba.

Ejemplo práctico
A continuación, se expone un trozo de código incorrecto (el método add, resta en vez de sumar) y una prueba unitaria mal diseñada:
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class Calculator {
int add(int a, int b) {
return a - b;
}
}
public class CalculatorTest {
@Test
void add_has_a_test_but_the_test_is_faulty_and_useless() {
Calculator calc = new Calculator();
int result = calc.add(2, 1); // With the bug, result is 1
assertTrue(result == result);
}
} Aunque la lógica del método es incorrecta (resta en lugar de sumar), la prueba unitaria asociada se ejecuta sin fallos. Esto ocurre porque la prueba únicamente comprueba que el resultado es igual a sí mismo, algo que siempre se cumple independientemente de la lógica implementada.
Como consecuencia, el código se considera probado y genera cobertura, ya que la función se ejecuta, pero en realidad no se está validando su comportamiento. Este ejemplo muestra que tener cobertura de código no garantiza que las pruebas unitarias, por sí solas, sean fiables ni efectivas para detectar comportamientos no deseados.
Anexo
A continuación, se muestra el listado de frameworks y herramientas permitidas, con sus versiones mínimas, para cada stack tecnológico.
| Stack | Framework | Versión mínima de lenguaje o runtime | Versión mínima del gestor de paquetes | Framework de testing permitido | Enlace framework de mutación-framework de testing | Documentación | Extra |
|---|---|---|---|---|---|---|---|
| Maven | Pitest-maven 1.20.3 | Java 11 | Maven 3.6.3 | JUnit5 | Mediante Bytecode |
| |
| Node | Stryker 8.5.0 | Typescript 4.8.0, Node 18 | NPM 8 | Jest 23+ | Mediante sistema de módulos | Stryker Runners | (!): No se permite el uso de navegadores dentro de Jest. Jenkins es incapaz de lanzar dichos navegadores (19/01/2026) |
| Php-composer | Infection 0.32.3 | PHP 8.2 | Composer 2.2 | PHPUnit 9+ | Mediante Code Coverage en formato PHPUnit XML | Infection Guide |
NOTA Para El stack de Node no se permite el uso de navegadores dentro de Jest. Jenkins es incapaz de lanzar dichos navegadores (19/01/2026)